package com.kmzx.one.project.service.impl;

import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.kmzx.one.common.exceptions.NoSuchObjectException;
import com.kmzx.one.common.exceptions.ParameterNullException;
import com.kmzx.one.common.utils.DateTimeUtils;
import com.kmzx.one.common.utils.UUIDGenerator;
import com.kmzx.one.project.config.wx.WxPayUtils;
import com.kmzx.one.project.entity.UserCashDetail;
import com.kmzx.one.project.entity.UserCashback;
import com.kmzx.one.project.entity.UserProfit;
import com.kmzx.one.project.entity.UserRankBuy;
import com.kmzx.one.project.entity.UserRankDetail;
import com.kmzx.one.project.entity.WxUser;
import com.kmzx.one.project.mapper.CustomerMapper;
import com.kmzx.one.project.mapper.UserCashMapper;
import com.kmzx.one.project.mapper.UserCashbackMapper;
import com.kmzx.one.project.mapper.UserProfitMapper;
import com.kmzx.one.project.mapper.UserRankBuyMapper;
import com.kmzx.one.project.mapper.UserRankMapper;
import com.kmzx.one.project.mapper.WxUserMapper;
import com.kmzx.one.project.others.common.TwoDays;
import com.kmzx.one.project.others.dto.FreightDetailInfo;
import com.kmzx.one.project.others.dto.FreightInfo;
import com.kmzx.one.project.others.dto.UserCashInfo;
import com.kmzx.one.project.others.dto.UserProfitDetailInfo;
import com.kmzx.one.project.others.dto.UserProfitInfo;
import com.kmzx.one.project.service.UserProfitService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

@Service
public class UserProfitServiceImpl implements UserProfitService {

    @Autowired
    private UserProfitMapper userProfitMapper;

    @Autowired
    UserCashbackMapper userCashbackMapper;

    @Autowired
    private CustomerMapper customerMapper;

    @Autowired
    private WxUserMapper wxUserMapper;

    @Autowired
    UserRankBuyMapper userRankBuyMapper;

    @Autowired
    WxPayUtils wxPayUtils;

    @Autowired
    UserCashMapper userCashMapper;

    @Autowired
    private UserRankMapper userRankMapper;

    @Override
    public UserProfitInfo findUserProfit(String userId) throws Exception {
        // todo 得到total,和userId
        UserProfitInfo dto = customerMapper.selectUserProfit(userId);
        if (dto == null) {
            return null;
        }

        List<UserProfitDetailInfo> detailss = userCashMapper.selectUserOutcomeDetails(userId, 1);
        BigDecimal cash = BigDecimal.ZERO;
        BigDecimal totalAmount = dto.getTotalAmount();
        if (!CollectionUtils.isEmpty(detailss)) {
            for (int i = 0; i < detailss.size(); i++) {
                if (detailss.get(i).getStates() != 2) {
                    cash = cash.add(detailss.get(i).getDetail());
                }
            }
        }
        //  can  1代表 没有提现订单记录
        dto.setCan(1);
        dto.setProfit(totalAmount);
        dto.setTotalAmount(dto.getCanPay());

        List<UserCashDetail> cashDetailList = userCashMapper.selectAllCashDetail(userId);
        if (!CollectionUtils.isEmpty(cashDetailList)) {
            // 有提现订单
//            dto.setCan(1);
            UserCashDetail detail = cashDetailList.get(0);
            Integer states = detail.getStates();
            Integer states1 = detail.getStates1();
            String reason2 = detail.getReason2();
            Integer read = detail.getCanRead();
            dto.setCashId(detail.getId());
            dto.setRead(read);
            if (states1 == null) {
                states1 = 100;
            }
            if (read == 1) {
                if (states == 0 || states == 1 && states1 != 6) {
                    dto.setCan(0);
                    dto.setCashId(detail.getId());
                } else if (states == 2 || states1 == 6 || states == 7) {
                    dto.setCan(1);
                } else if (states == 3) {
                    dto.setCan(1);
                }
            } else {
                dto.setCan(0);
            }
        }

        int withdrawAllow = checkWithdrawAllow();
        dto.setWithdraw(withdrawAllow);
//        userCashMapper.h


        Date yesterdayZero = DateTimeUtils.getYesterdayZero();
        Date yesterdayEnd = DateTimeUtils.getYesterdayEnd();

        BigDecimal yetAmount = customerMapper.selectUserYetAmount(userId, yesterdayZero, yesterdayEnd);
        if (yetAmount == null) {
            yetAmount = BigDecimal.ZERO;
        }
        dto.setYetAmount(yetAmount);
        PageHelper.startPage(1, 10);
        List<UserProfitDetailInfo> details = userCashMapper.selectUserOutcomeDetails(userId, 1);
        dto.setIncomes(details);
        return dto;
    }

    @Override
    public List<UserProfitDetailInfo> findUserInOrOutcomeMore(String userId, Integer pageNum, Integer pageSize, int type) throws Exception {
        if (type == 1) {
            PageHelper.startPage(pageNum, pageSize, true);
            Page<UserProfitDetailInfo> details = userProfitMapper.selectUserProfitDetails(userId, 1);
            if (details.getResult() != null && details.getResult().size() > 0) {
                for (UserProfitDetailInfo detail : details) {
                    if (detail.getInfo() == null) {
                        detail.setInfo(detail.getRemark());
                    }
                }
            }
            return details;

        } else {
            PageHelper.startPage(pageNum, pageSize, true);
//            Page<UserProfitDetailInfo> details = userProfitMapper.selectUserOutcomeDetails(userId, 1);
            Page<UserProfitDetailInfo> details = userCashMapper.selectUserOutcomeDetails(userId, 1);
            Page<UserProfitDetailInfo> details2 = userCashMapper.selectUserProfitDetails(userId, 1);
            ArrayList<UserProfitDetailInfo> detailInfos = new ArrayList<>();
            if (!CollectionUtils.isEmpty(details2)) {
                detailInfos.addAll(details2);
            }
            if (!CollectionUtils.isEmpty(details)) {
                detailInfos.addAll(details);
            }
            if (!CollectionUtils.isEmpty(detailInfos)) {
                detailInfos.forEach(upi -> {
                    upi.setAvatar(null);
                    if (upi.getRealMoney() == null) {
                        upi.setRealMoney(upi.getDetail());
                    }
                });
                detailInfos.sort(Comparator.comparing(UserProfitDetailInfo::getDate).reversed());
                return detailInfos;
            }
            return details;
        }
    }

    @Override
    public Integer doUserCashBack(String userId, BigDecimal money) throws Exception {
        if (money != null && money.compareTo(BigDecimal.ZERO) > 0) {
            Date date = new Date();
            UserCashback userCashback = new UserCashback();
            userCashback.setId(UUIDGenerator.generate());
            userCashback.setCreateTime(date);
            userCashback.setUpdateTime(date);
            userCashback.setBackMoney(money);
            userCashback.setCashCode(UUIDGenerator.generateOrderNo("TX"));
            userCashback.setState(0);
            userCashback.setUserId(userId);
            userCashback.setCanRead(0);
            UserProfitInfo dto = customerMapper.selectUserProfit(userId);
            if (dto.getCanPay().compareTo(money) >= 0) {
                BigDecimal endMoney = dto.getCanPay().subtract(money);
                UserProfit profit = new UserProfit();
                profit.setId(dto.getTemps());
                profit.setProfitMoney(endMoney);
                profit.setUpdateTime(date);
                int end = userProfitMapper.updateByIdSelective(profit);
                int insert = userCashbackMapper.insert(userCashback);
                return insert + end;
            } else {
                return -1;
            }
        } else {
            throw new ParameterNullException("该提现金额输入有误!");
        }
    }

    @Override
    public UserCashInfo findUserCashInfo(String userId, String cashId) throws Exception {
        UserCashDetail end = userCashMapper.selectKey(cashId);
        if (end != null) {
            UserCashDetail detail = new UserCashDetail();
            detail.setId(cashId).setCanRead(1);
            userCashMapper.updateByIdSelect(detail);
            UserCashInfo cashInfo = new UserCashInfo(end.getId(), end.getReason(), end.getUserCashCodes(), end.getStates());
            cashInfo.setApplyMoney(end.getApplyMoney()).setRealMoney(end.getSettlementMoney());
            Integer states1 = end.getStates1();
            if (states1 != null) {
                if (states1 == 6) {
                    cashInfo.setReason(end.getReason());
                }
            }
            if (end.getStates() == 2) {
                cashInfo.setReason(end.getReason2());
            }
            cashInfo.setStates(end.getStates());
            return cashInfo;
        } else {
            throw new NoSuchObjectException("暂无该提现订单");
        }
    }

    @Override
    public Integer doReadCash(String cashId) throws Exception {
//        UserCashback cashback = new UserCashback();
//        cashback.setId(cashId);
//        cashback.setCanRead(1);
//        cashback.setUpdateTime(new Date());
//        userCashbackMapper.updateByIdSelective(cashback);

        UserCashDetail detail = new UserCashDetail();
        detail.setId(cashId).setCanRead(1);
        userCashMapper.updateByIdSelect(detail);
        return 0;
    }

    @Override
    public FreightInfo findUserFreight(String userId) throws Exception {
        FreightInfo dto = customerMapper.selectUserFreight(userId);
        if (dto == null) {
            dto = new FreightInfo();
        }
        if (dto.getMoney() == null) {
            dto.setMoney(BigDecimal.ZERO);
        }
        Date yesterdayEnd = DateTimeUtils.getYesterdayEnd();
        Date yesterdayZero = DateTimeUtils.getYesterdayZero();

        BigDecimal yetMoney = customerMapper.sumYetMoney(userId, yesterdayZero, yesterdayEnd);
        if (yetMoney == null) {
            yetMoney = BigDecimal.ZERO;
        }
        dto.setYetMoney(yetMoney);
        PageHelper.startPage(0, 1000);
        List<FreightDetailInfo> list = customerMapper.selectUserFreightPager(userId);
        dto.setDetails(list);
        return dto;
    }

    @Override
    public List<FreightDetailInfo> findUserFreightPager(String userId, Integer pageNum, Integer pageSize) throws Exception {
        PageHelper.startPage(pageNum, pageSize, true);
        List<FreightDetailInfo> list = customerMapper.selectUserFreightPager(userId);
        return list;
    }

    @Override
    public Object doBuyUserRanks(String userId, BigDecimal money) throws Exception {
        // rankBuyCallback
        UserRankBuy userRankBuy = new UserRankBuy();
        userRankBuy.setUserId(userId);
        userRankBuy.setId(UUIDGenerator.generate());
        userRankBuy.setStates(1);
        userRankBuy.setPayMoney(money);
        // PGSC  RG rank Buy
        userRankBuy.setOrdersCode(UUIDGenerator.generateOrderNo("PGRB"));
        userRankBuyMapper.insert(userRankBuy);
        WxUser wxUser = wxUserMapper.selectById(userId);

        WxPayMpOrderResult orderResult = wxPayUtils.payUserRankBuy(UUIDGenerator.generate(), wxUser.getOpenId(), money, userRankBuy.getOrdersCode(), "快美甄选,购买等级支付:" + userRankBuy.getOrdersCode(), userRankBuy.getId());
//            orderResult.get
        logger.info("订单支付返回数据:{}", orderResult);
        return orderResult;
    }

    // 我已经提现了的金额
    @Override
    public BigDecimal myEverWithdraw(String userId) {
        BigDecimal withdraw = userCashbackMapper.myAllEverWithdraw(userId);
        if (withdraw == null) {
            return BigDecimal.ZERO;
        }
        return withdraw;
    }

    @Override
    public int checkWithdrawAllow() {
        TwoDays days = responseCashDate();
        Date date = new Date();
        long timeLong = date.getTime();
        long daysAgoLong = days.getStart().getTime();
        if (timeLong < daysAgoLong) {
            return 0;
        } else if (timeLong >= daysAgoLong) {
            if (timeLong > days.getEnd().getTime()) {
                return 0;
            } else {
                return 1;
            }
        }
        return 0;
    }

    @Override
    public String findUserProfitMsg(String userId, String tempId) {
        // //0-自己消费1会员返利2非会员返利3退款4退回5购买货仓6消费货仓7订单取消退回8消费余额9返美颜值
        UserRankDetail detail = userRankMapper.selectRankDetailById(tempId);
        if (detail != null) {
            String profitInfo = detail.getProfitInfo();
            if (profitInfo != null) {
                return detail.getProfitInfo();
            } else {
                return detail.getRemark();
            }
        }
        return null;
    }


    public TwoDays responseCashDate() {
        LocalDateTime now = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        LocalDateTime dayOfMonth = now.with(TemporalAdjusters.firstDayOfMonth());
        LocalDateTime plusDays = dayOfMonth.plusDays(25);

        Instant instant = plusDays.atZone(ZoneId.systemDefault()).toInstant();
        Date daysAgo25 = Date.from(instant);

        LocalDateTime end = now.with(TemporalAdjusters.lastDayOfMonth());

        Instant instantEnd = end.atZone(ZoneId.systemDefault()).toInstant();
        Date daysEnd = Date.from(instantEnd);

        TwoDays twoDays = new TwoDays();
        twoDays.setStart(daysAgo25).setEnd(daysEnd);
        return twoDays;
    }

}
